package com.example.weixinapireptile.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.weixinapireptile.api.RedisCache;
import com.example.weixinapireptile.api.WeiXinApi;
import com.example.weixinapireptile.common.base.BaseController;
import com.example.weixinapireptile.common.result.PageResult;
import com.example.weixinapireptile.common.result.Result;
import com.example.weixinapireptile.job.WeixinDataPqHandler;
import com.example.weixinapireptile.model.WxResultBody;
import com.example.weixinapireptile.common.okhttp.MyCookieStore;
import com.example.weixinapireptile.pojo.entity.WxArticle;
import com.example.weixinapireptile.pojo.query.WxArticleQuery;
import com.example.weixinapireptile.pojo.vo.WxArticleVO;
import com.example.weixinapireptile.reptile.SpiderUtil;
import com.example.weixinapireptile.service.IWxArticleService;
import com.example.weixinapireptile.common.utils.HttpUtils;
import com.taobao.api.ApiException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Cookie;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信公众号爬取-API
 *
 * @author xunuo
 * @datetime 2023年 10月 26日 15:01
 */
@Api(tags = "微信文章爬取API")
@RestController
@RequestMapping("/reptile/wxArticle")
@Slf4j
public class WxArticleController extends BaseController {


    @Autowired
    private IWxArticleService wxArticleService;
    @Autowired
    RedisCache redisCache;
    @Autowired
    private WeixinDataPqHandler wxDataPqHandler;

    /**
     * 生成二维码
     *
     * @param resp
     * @author xunuo
     * @date 15:42 2023/11/3
     **/
    @ApiOperation(value = "生成二维码")
    @GetMapping("/getImage")
    public void getImage(HttpServletResponse resp) throws IOException {
        // 1. POST请求开始登录接口，初始化cookie
        redisCache.deleteObject("cookie");
        redisCache.deleteObject("token");
        resp.setContentType("image/jpeg");
        // 1. POST请求开始登录接口，初始化cookie
        String sessionid = "" + System.currentTimeMillis() + (int) (Math.random() * 100);
        WxResultBody wxResultBody = WeiXinApi.startLogin(sessionid);
        // 2. 请求获取二维码图片接口，得到流
        InputStream inputStream = WeiXinApi.getQRCode();
        // 从输入流中读取图片数据
        BufferedImage image = ImageIO.read(inputStream);
        //转成图片显示
        ServletOutputStream outputStream = resp.getOutputStream();
        ImageIO.write(image, "jpg", outputStream);
        outputStream.close();
        outputStream.flush();

    }

    /**
     * 查询登录状态
     *
     * @author xunuo
     * @date 10:41 2023/11/8
     **/
    @ApiOperation(value = "查询登录状态")
    @RequestMapping("/askQRCode")
    public Result askQRCode() throws IOException {
        WxResultBody askQrCode = WeiXinApi.askQRCode();
        Integer status = askQrCode.getStatus();
        if (status != 1) {
            return Result.failed("用户未登录！");
        }
        WxResultBody bizlogin = WeiXinApi.bizlogin();
        if (StringUtils.isNotEmpty(bizlogin.getErr_msg())) {
            return Result.failed("登陆失败！");
        }
        //重定向地址
        String redirect_url = bizlogin.getRedirect_url();
        //解析成键值对
        Map<String, String> loginRes = HttpUtils.parseQueryParams(redirect_url);
        //得到token
        String token = loginRes.get("token");
        //设置全局token值
        MyCookieStore.setToken(token);
        // TODO 把token持久化
        redisCache.setCacheObject("token", token);
        return Result.success();
    }

    /**
     * 处理数据爬取  爬取最近的数据
     *
     * @return org.extractor.common.result.Result
     * @author xunuo
     * @date 15:42 2023/11/3
     **/
    @ApiOperation(value = "爬取最近的数据-开始爬取数据")
    @PostMapping("/start")
    public Result bizLogin() throws ApiException {
        String runstatus = redisCache.getCacheObject("wxpqrunstatus");
        if (!StringUtils.isNotEmpty(runstatus)) {
            runstatus="0";
            redisCache.setCacheObject("wxpqrunstatus", "0");
        }
        if (runstatus.equals("1")) {
            return Result.failed("当前公众号正在爬取.....！");
        }
        String token = redisCache.getCacheObject("token");
        if (token == null) {
            return Result.failed("请先扫码登录！");
        }
        MyCookieStore.setToken(token);
        redisCache.setCacheObject("wxpqrunstatus","1");
        redisCache.expire("wxpqrunstatus",3, TimeUnit.MINUTES);
        wxArticleService.reptileWxArticle();
        redisCache.setCacheObject("wxpqrunstatus","0");
        return Result.success();
    }

    @GetMapping("/pages")
    @ApiOperation(value = "分页列表")
    public PageResult<WxArticleVO> list(WxArticleQuery wxArticleQuery) {
        startPage();
        return PageResult.success(wxArticleService.listPages(wxArticleQuery));
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "详情")
    public Result<WxArticleVO> list(@PathVariable String id) {
        return Result.success(wxArticleService.getWxArticleById(id));
    }

    /**
     *
     */
    @GetMapping("/test")
    public Result test() {
        String token = redisCache.getCacheObject("token");
        MyCookieStore.setToken(token);
        return Result.success(wxArticleService.test());
    }

    /**
     * 爬取全部历史数据
     *
     * @return
     */
    @GetMapping("/pqhistory")
    public Result startPqHistory() throws ApiException {
        String runstatus = redisCache.getCacheObject("wxpqrunstatus");
        if (!StringUtils.isNotEmpty(runstatus)) {
            runstatus="0";
            redisCache.setCacheObject("wxpqrunstatus", "0");
        }
        String token = redisCache.getCacheObject("token");
        if (token == null) {
            return Result.failed("请先扫码登录！");
        }
        MyCookieStore.setToken(token);
        redisCache.setCacheObject("wxpqrunstatus","1");
        redisCache.expire("wxpqrunstatus",3, TimeUnit.MINUTES);
        wxDataPqHandler.paiquHistory();
        redisCache.setCacheObject("wxpqrunstatus","0");
        return Result.success();
    }

    /**
     * 爬取指定公众号历史数据
     *
     * @return
     */
    @GetMapping("/pqhistoryone/{id}")
    public Result startPqHistory(@PathVariable String id) throws ApiException {
        String runstatus = redisCache.getCacheObject(id + "runstatus");
        if (!StringUtils.isNotEmpty(runstatus)) {
            runstatus="0";
            redisCache.setCacheObject(id + "runstatus", "0");
        }
        if (!StringUtils.isNotEmpty(runstatus) || runstatus.equals("1")) {
            return Result.failed("当前公众号正在爬取.....！");
        }

        String token = redisCache.getCacheObject("token");
        if (token == null) {
            return Result.failed("请先扫码登录！");
        }
        MyCookieStore.setToken(token);

        redisCache.setCacheObject(id + "runstatus", "1");
        redisCache.expire(id + "runstatus",3, TimeUnit.MINUTES);
        try {
            wxDataPqHandler.paiquHistoryOne(id);
        } catch (Exception e) {
            redisCache.setCacheObject(id + "runstatus", "0");
        }

        return Result.success();
    }


    @GetMapping("/getTokenCookie")
    public String getTokenCookie() {
        HashMap<String, String> res = new HashMap<>();
        String token = redisCache.getCacheObject("token");
        List<Cookie> cookie = MyCookieStore.getCookie();
        res.put("token", token);
        res.put("cookie", cookie.toString());
        return JSON.toJSONString(res);
    }

    /**
     *
     */
    @GetMapping("/getHtml")
    public void getHtml(){
        List<WxArticle> list = wxArticleService.list(new LambdaQueryWrapper<WxArticle>().isNull(WxArticle::getHtmlContent));
        int count = 0;
        for (WxArticle wxArticle : list) {
            String link = wxArticle.getLink();
            String html = SpiderUtil.getHTML(link);
            wxArticle.setHtmlContent(html);
            wxArticleService.updateById(wxArticle);
            System.out.println("fffffffffffffffff==1111======="+count++);
        }
    }
    //导出文档
    @GetMapping("/exportTxt")
    public void export(){
        List<WxArticle> list = wxArticleService.list(new LambdaQueryWrapper<WxArticle>()
                .eq(WxArticle::getExportFlag,"0"));
        for (WxArticle wxArticle : list) {
            wxArticle.setExportFlag("1");
            //将String写入文件，覆盖模式，字符集为UTF-8
            String content = wxArticle.getContent();
            String path = "/txt/"+wxArticle.getId()+".txt";
            //path指定路径下的文件如不存在，则创建
            try {
                File file = FileUtil.writeUtf8String(content, new File(path));
                wxArticleService.updateById(wxArticle);
            } catch (IORuntimeException e) {
                //抛出一个运行时异常(直接停止掉程序)
                throw new RuntimeException("运行时异常", e);
            }
        }
    }


}
